import json
from prg.entity.head_entity import HeadEntity
from prg.common.common_base import CommonBase
from prg.entity.arg_entity import ArgBase


class HeaderInfo:

    def __init__(self, client_socket=None):
        self.command = None
        self.arg = None
        self.bind = False
        self.name = None
        self.addr = None
        self.client_socket = client_socket
        if client_socket:
            self.read_header()

    def get_name(self):
        self.name

    def set_name(self, name):
        self.name = name

    def get_addr(self):
        return self.addr

    def get_command(self):
        return self.command

    def set_command(self, command):
        self.command = command

    def get_arg(self):
        return self.arg

    def set_arg(self, arg):
        self.arg = arg

    def get_bind(self):
        return self.bind

    def get_client_socket(self):
        return self.client_socket

    def bind_header(self, name, command, arg):
        head_en = HeadEntity()
        head_en.command = command
        head_en.arg = arg
        head_en.name = name
        self.command = command
        self.name = name
        self.arg = arg
        self.bind = True
        return head_en

    def get_head_entity(self, key=None):
        head = HeadEntity()
        head.command = self.command
        head.name = self.name
        if key is None:
            head.arg = self.arg
        else:
            arg_entity = CommonBase.aes_decrypt_json(key=key, data=self.arg, en=ArgBase())
            head.arg = arg_entity
        return head

    def read_header(self):
        # h = client_socket.recv(4, socket.MSG_WAITALL)
        h, len_addr = self.read_socket_data(4)
        if len(h) > 0:
            header_len = int.from_bytes(h, byteorder='big', signed=False)
            head_bytes, addr = self.read_socket_data(length=header_len, addr=len_addr)
            self.addr = addr
            json_str = str(head_bytes, 'utf-8')
            # print("header json string: %s" % json_str)
            header = json.loads(json_str)
            header_item = CommonBase.dict_to_entity(dict_item=header, en=HeadEntity())
            self.bind_header(name=header_item.name, command=header_item.command, arg=header_item.arg)
        return self

    def read_socket_data(self, length, addr=None):
        read_byte = bytes()
        bytes_len = len(read_byte)
        while bytes_len < length:
            read_len = 1024 if length - bytes_len > 1024 else length - bytes_len
            read_byte_tmp, read_addr_tmp = self.client_socket.recvfrom(read_len)
            if addr is not None and read_addr_tmp != addr:
                raise Exception("Invalid Address")
            read_byte += read_byte_tmp
            bytes_len = len(read_byte)
        return read_byte, read_addr_tmp
